1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package com.google.common.collect;
16
17 import static com.google.common.base.Preconditions.checkNotNull;
18 import static com.google.common.base.Preconditions.checkPositionIndexes;
19 import static com.google.common.collect.BoundType.CLOSED;
20
21 import com.google.common.primitives.Ints;
22
23 import javax.annotation.Nullable;
24
25
26
27
28
29
30 @SuppressWarnings("serial")
31 final class RegularImmutableSortedMultiset<E> extends ImmutableSortedMultiset<E> {
32 private final transient RegularImmutableSortedSet<E> elementSet;
33 private final transient int[] counts;
34 private final transient long[] cumulativeCounts;
35 private final transient int offset;
36 private final transient int length;
37
38 RegularImmutableSortedMultiset(
39 RegularImmutableSortedSet<E> elementSet,
40 int[] counts,
41 long[] cumulativeCounts,
42 int offset,
43 int length) {
44 this.elementSet = elementSet;
45 this.counts = counts;
46 this.cumulativeCounts = cumulativeCounts;
47 this.offset = offset;
48 this.length = length;
49 }
50
51 @Override
52 Entry<E> getEntry(int index) {
53 return Multisets.immutableEntry(
54 elementSet.asList().get(index),
55 counts[offset + index]);
56 }
57
58 @Override
59 public Entry<E> firstEntry() {
60 return getEntry(0);
61 }
62
63 @Override
64 public Entry<E> lastEntry() {
65 return getEntry(length - 1);
66 }
67
68 @Override
69 public int count(@Nullable Object element) {
70 int index = elementSet.indexOf(element);
71 return (index == -1) ? 0 : counts[index + offset];
72 }
73
74 @Override
75 public int size() {
76 long size = cumulativeCounts[offset + length] - cumulativeCounts[offset];
77 return Ints.saturatedCast(size);
78 }
79
80 @Override
81 public ImmutableSortedSet<E> elementSet() {
82 return elementSet;
83 }
84
85 @Override
86 public ImmutableSortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
87 return getSubMultiset(0, elementSet.headIndex(upperBound, checkNotNull(boundType) == CLOSED));
88 }
89
90 @Override
91 public ImmutableSortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
92 return getSubMultiset(elementSet.tailIndex(lowerBound, checkNotNull(boundType) == CLOSED),
93 length);
94 }
95
96 ImmutableSortedMultiset<E> getSubMultiset(int from, int to) {
97 checkPositionIndexes(from, to, length);
98 if (from == to) {
99 return emptyMultiset(comparator());
100 } else if (from == 0 && to == length) {
101 return this;
102 } else {
103 RegularImmutableSortedSet<E> subElementSet =
104 (RegularImmutableSortedSet<E>) elementSet.getSubSet(from, to);
105 return new RegularImmutableSortedMultiset<E>(
106 subElementSet, counts, cumulativeCounts, offset + from, to - from);
107 }
108 }
109
110 @Override
111 boolean isPartialView() {
112 return offset > 0 || length < counts.length;
113 }
114 }